package puzzle.sudoku.solver;

import puzzle.common.data.HatanException;
import puzzle.common.solver.BoardRule;
import puzzle.sudoku.data.SudokuBoard;
import tomoto.util.FastBitSet;

class NumberPossibilityRule implements BoardRule<SudokuBoard> {

	public boolean apply(SudokuBoard b) throws HatanException {
		boolean isChanged = false;

		for (int y = 0; y < b.height; y++) {
			for (int x = 0; x < b.width; x++) {
				if (b.getNumber(x, y) == 0) {
					{
						FastBitSet f = b.getForbiddenFlags(x, y);
						int forbiddenCount = f.countBits();
						if (forbiddenCount == b.width - 1) {
							int n = f.find(false, 0) + 1;
							isChanged |= b.setNumber(x, y, n);
						} else if (forbiddenCount == b.width) {
							throw new HatanException();
						}
					}
					
					{
						FastBitSet f = b.getComplementalForbiddenFlags(x, y);
						int possibleCount = f.countBits();
						if (possibleCount == 1) {
							int n = f.find(true, 0) + 1;
							isChanged |= b.setNumber(x, y, n);
						} else {
							if (possibleCount != 0) {
								throw new HatanException();
							}
						}
					}
				}
			}
		}
		
		return isChanged;
	}

}
